package com.yanqu.road.server.gameplayer.module.activity.newyearbag;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.newyearbag.NewYearBagConfig;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eGoodsType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.ePlayerAttrType;
import com.yanqu.road.entity.log.LogNewYearBagChange;
import com.yanqu.road.entity.player.UserActivityRealReward;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.pb.activity.NewYearBagProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.manger.activity.newyearbag.NewYearBagMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.pb.NewYearBagPb;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

public class NewYearBagModule extends GeneralModule {

    private final Object loginRewardLock = new Object();

    public void checkLoginReward() {
        synchronized (loginRewardLock) {
            if (!NewYearBagMgr.inLoginRewardTime()) {
                return;
            }

            long now = System.currentTimeMillis();
            long lastTime = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.NewYearBagLoginRewardTime);
            if (now - DateHelper.getZeroTimeStamp(lastTime) < DateHelper.DAY_MILLIONS) {
                return;
            }

            // 修改状态
            player.getModule(AttributeModule.class).setAttribute(ePlayerAttrType.NewYearBagLoginRewardTime, now);

            // 领奖
            NewYearBagConfig config = NewYearBagMgr.getNewYearBagConfig();
            String reward = config.getLoginReward();
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.NewYearBag, eLogMoneyType.NewYearBagLoginReward);
        }
    }

    public void refreshConfigAndData() {
        NewYearBagConfig config = NewYearBagMgr.getNewYearBagConfig();
        if (config != null) {
            NewYearBagProto.NewYearBagSyncConfigRespMsg.Builder configRespMsg = NewYearBagPb.parseNewYearBagSyncConfigRespMsg(config);

            String appId = player.getAppId();
            String resultQrCode = "";
            if (StringUtils.isNullOrEmpty(appId)){
                appId = "default";
            }

            JSONObject dataObj  = JSONObject.parseObject(ChannelConfig.NEW_YEAR_BAG_SHARE_QR_CODE);
            if (dataObj != null){           //解析出来不为空
                String dataObjString = dataObj.getString(appId);
                if (dataObjString != null){             //有这个key才赋值
                    resultQrCode = dataObjString;
                }
                if(StringUtils.isNullOrEmpty(resultQrCode) && dataObj.containsKey("default")){
                    resultQrCode = dataObj.getString("default");
                }
            }
            configRespMsg.setShowQr(ChannelConfig.NEW_YEAR_BAG_DISPLAY_QR_CODE);
            configRespMsg.setQrCode(resultQrCode);
            player.sendPacket(ClientProtocol.U_NEW_YEAR_BAG_SYNC_CONFIG, configRespMsg);
        }
    }

    public int openByCmd(int num) {
        NewYearBagConfig config = NewYearBagMgr.getNewYearBagConfig();

        // 数量校验
        if (num <= 0 || num >= 9999) {
            return GameErrorCode.E_USE_ITEM_NUM_ERROR;
        }

        // 预扣除红包
        Property cost = new Property();
        cost.addProperty(config.getHongBaoId(), BigInteger.valueOf(num));
        if (!player.getModule(CurrencyModule.class).currencyIsEnough(cost)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        player.getModule(PreReduceModule.class).preReduce(cost);

        // 到跨服打开
        NewYearBagProto.CrossNewYearBagOpenReqMsg.Builder builder = NewYearBagProto.CrossNewYearBagOpenReqMsg.newBuilder();
        builder.setActivityId(config.getActivityInfo().getActivityId());
        builder.setNum(num);
        builder.setOpenId(player.getUserInfo().getOpenId());
        builder.setRecentRechargeVip(0); // 不需要了
        builder.setPlayerBaseData(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
        builder.setDeviceId(StringUtils.isNullOrEmpty(player.getDeviceId()) ? "" : player.getDeviceId());
        player.sendPacket(CrossProtocol.C2_NEW_YEAR_BAG_OPEN, builder);

        return 0;
    }

    public int openFromCross(int num, NewYearBagProto.NewYearBagOpenRespMsg respMsg) {
        NewYearBagConfig config = NewYearBagMgr.getNewYearBagConfig();

        // 返还预扣除
        Property cost = new Property();
        cost.addProperty(config.getHongBaoId(), BigInteger.valueOf(num));
        player.getModule(PreReduceModule.class).restorePreReduce(cost);

        // 抽失败
        if (respMsg.getRet() != 0) {
            return respMsg.getRet();
        }

        // 统计奖励(非实物)
        List<String> rewardStrList = StringUtils.stringToStringList(respMsg.getReward(), "#");
        Property allRewardProp = new Property();
        for (String rewardStr : rewardStrList) {
            allRewardProp.addProperty(PropertyHelper.parseStringToProperty(rewardStr));
        }
        String allRewardStr = PropertyHelper.parsePropertyToString(allRewardProp);

        // 扣道具
        if (!player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.NewYearBag, eLogMoneyType.NewYearBagOpen)) {
            Property logProperty = new Property();
            for (String award : respMsg.getRealRewardList()) {
                logProperty.addProperty(PropertyHelper.parseStringToProperty(award));
            }
            logProperty.addProperty(allRewardProp);
            log.info("open new year bag from cross error ! item no enough. userId {} num {}, reward {}.", getUserId(), num, PropertyHelper.parsePropertyToString(logProperty));
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        NewYearBagProto.NewYearBagOpenRespMsg.Builder builder = NewYearBagProto.NewYearBagOpenRespMsg.newBuilder();
        for (String rewardStr : rewardStrList) {
            // 日志
            AutoLogMgr.add(new LogNewYearBagChange(getUserId(), config.getHongBaoId(), 1, eLogMoneyType.NewYearBagOpen.getValue(), rewardStr));
            // 发奖励
            Property reward = PropertyHelper.parseStringToProperty(rewardStr);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.NewYearBag, eLogMoneyType.NewYearBagOpen);
        }

        //处理实物奖励
        for (String realReward : respMsg.getRealRewardList()) {
            Property reward = PropertyHelper.parseStringToProperty(realReward);
            //实物奖励记录
            for (Map.Entry<Integer, BigInteger> entry : reward.getGoods().entrySet()) {
                GoodsInfo goodsInfo = GoodsMgr.getGoodsById(entry.getKey());
                if(goodsInfo == null){
                    continue;
                }
                if(goodsInfo.getType() == eGoodsType.ActivityRealReward.getValue()){
                    // 日志
                    AutoLogMgr.add(new LogNewYearBagChange(getUserId(), config.getHongBaoId(), 1, eLogMoneyType.NewYearBagOpen.getValue(), goodsInfo.getGoodsId() + "=" + entry.getValue().toString()));

                    UserActivityRealReward uerRealReward = player.getModule(ActivityRealRewardModule.class).addRealReward(config.getActivityInfo().getActivityId(), goodsInfo.getGoodsId(), entry.getValue().intValue());
                    builder.addRealRewardNo(uerRealReward.getNo());
                }
                break;
            }
        }

        // 返回
        builder.setRet(0);
        builder.setReward(allRewardStr);
        builder.addAllRewardId(respMsg.getRewardIdList());
        builder.addAllRealRewardNo(respMsg.getRealRewardNoList());
        builder.addAllRealReward(respMsg.getRealRewardList());
        player.sendPacket(ClientProtocol.U_NEW_YEAR_BAG_OPEN, builder);

        return 0;
    }

    public int getRecordByCmd() {
        ActivityInfo activityInfo = NewYearBagMgr.getActivityInfo();
        NewYearBagProto.CrossNewYearBagRecordReqMsg.Builder builder = NewYearBagProto.CrossNewYearBagRecordReqMsg.newBuilder();
        builder.setActivityId(activityInfo.getActivityId());
        builder.setResp(NewYearBagProto.NewYearBagRecordRespMsg.newBuilder().setRet(0));
        player.sendPacket(CrossProtocol.C2_NEW_YEAR_BAG_RECORD, builder);
        return 0;
    }

    public void addHongBaoByFuDai(int goodsId, int num, int son) {

        Property allReward = new Property();
        for (int i = 0; i < num; i++) {
            OpenGoodsBagResult result = GoodsBagMgr.getRandomGoods(goodsId);
            allReward.addProperty(result.getReward());
        }

        // 日志
        String rewardStr = PropertyHelper.parsePropertyToString(allReward);
        AutoLogMgr.add(new LogNewYearBagChange(getUserId(), goodsId, num, son, rewardStr));

        // 容错，奖励内不能再有福袋，不然死循环了
        allReward.removeProperty(goodsId);

        // 加奖励
        player.getModule(CurrencyModule.class).addCurrency(allReward, eLogMoneyType.NewYearBag, eLogMoneyType.NewYearBagRain);

        NewYearBagProto.NewYearSyncGetFuDaiRespMsg.Builder builder = NewYearBagProto.NewYearSyncGetFuDaiRespMsg.newBuilder();
        builder.setOpenReward(rewardStr);
        player.sendPacket(ClientProtocol.U_NEW_YEAR_BAG_SYNC_FU_DAI, builder);
    }


    public NewYearBagModule(GamePlayer player) {
        super(player);
    }

    @Override
    public void afterLogin() {
        refreshConfigAndData();
        checkLoginReward();
        log.debug("NewYearBagModule is new code...");
    }

    @Override
    public boolean loadData() {
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        return true;
    }
}
